package com.zzyl.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.zzyl.constant.ResouceConstant;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.ResourceListDTO;
import com.zzyl.dto.ResponseDto;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static com.zzyl.constant.SuperConstant.BUTTON;


@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;


    @Override

    @Caching(
            evict = {
                    @CacheEvict(cacheNames = ResouceConstant.RESOURCE_TREE,allEntries = true),
                    @CacheEvict(cacheNames = ResouceConstant.RESOURCE_LIST,allEntries = true),
            }
    )
    public void add(ResponseDto dto) {
        //dto转entity
        Resource resource = BeanUtil.copyProperties(dto, Resource.class);
        boolean isButton =  Objects.equals(dto.getResourceType(), BUTTON);
        // 判断父菜单是否大于2级
        String s = NoProcessing.processString(dto.getParentResourceNo());
        if (!isButton && s.length() > 12){
            //说明父菜单但已经是3级菜单
            throw  new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);
        }
        // 生成resource_no
        String resourceNo = null;
        // 先判断父菜单有没有子菜单
        Resource maxChild  =  resourceMapper.selectMaxNoChild(dto.getParentResourceNo());
        // 如果没有，父菜单的编号 +
        if (maxChild==null){
            resourceNo = NoProcessing.createNo(dto.getParentResourceNo(),false);

        }else {
            // 如果有，父菜单下的编号最大的子菜单的编号，+1生成兄弟编号
            resourceNo = NoProcessing.createNo(maxChild.getResourceNo(),true);
        }
            resource.setResourceNo(resourceNo);
            resourceMapper.insertSelective(resource);

    }



    @Override
    public List<Resource> getByUserId(Long userId,String DATA_STATE_0, String DATA_STATE_1) {
        return resourceMapper.selectByUserId(userId,DATA_STATE_0,DATA_STATE_1);
    }


    @Override
    //往缓存里添加
    @Cacheable(cacheNames = ResouceConstant.RESOURCE_LIST,key = "#dto.hashCode()")
    public List<Resource> list(ResourceListDTO dto) {
        return resourceMapper.list(dto);
    }


    @Override
    @Cacheable(cacheNames = ResouceConstant.RESOURCE_TREE,key = "''")
    public TreeVo tree() {
        // 查询出拉平的所有的菜单， data_state=0 resource_type=m parent_resource_no like 100001%
        String dataState = SuperConstant.DATA_STATE_0;
        String resourceType = SuperConstant.MENU;
        String parentResourceNo = NoProcessing.processString(SuperConstant.ROOT_PARENT_ID);
        List<Resource> resources = resourceMapper.tree(dataState, resourceType, parentResourceNo);
        //log.info(resources.toString());
        // 拉平的结构转化成树形结构
        TreeVo treeVo =new TreeVo();
        // 根节点
        TreeItemVo rootItem  =new TreeItemVo();
        rootItem.setId(SuperConstant.ROOT_PARENT_ID);
        rootItem.setLabel(SuperConstant.ROOT_PARENT_LABEL);
        if (CollectionUtils.isEmpty(resources)){
            return  treeVo;
        }
        // 把数据库中resource转化成TreeItemVo
        List<TreeItemVo> treeItemVos = resourcesToItemVo(resources);
        // 树形处理，从所有的菜单中找rootItem的子菜单
        tree(rootItem,treeItemVos);
        treeVo.setItems(Arrays.asList(rootItem));
        return treeVo;

    }


    private void tree(TreeItemVo rootItem, List<TreeItemVo> treeItemVos) {
        String parentId = rootItem.getId();
        for (TreeItemVo treeItemVo : treeItemVos) {
            if (Objects.equals(parentId,treeItemVo.getParentId())){
                rootItem.getChildren().add(treeItemVo);

                // 递归处理子菜单
                tree(treeItemVo,treeItemVos);
            }
        }
    }

    private List<TreeItemVo> resourcesToItemVo(List<Resource> resources) {
        List<TreeItemVo> voList=new ArrayList<>();
        for (Resource resource : resources) {
            TreeItemVo vo =new TreeItemVo();
            vo.setId(resource.getResourceNo());
            vo.setLabel(resource.getResourceName());
            vo.setChildren(new ArrayList<>());
            vo.setParentId(resource.getParentResourceNo());

            voList.add(vo);

        }
        return voList;
    }
}
